AmazonLinuxで作成したvirtualenvの環境でmarkupsafeを使おうとしたらImportErrorが発生した時の対処法
サーモン大好き、横山です。
今やってる作業で、 AmazonLinuxの virtualenv
をそのまま利用すると、ImportErrorが発生して困ったことになりました。
その時対処した手順を紹介します。
発生環境
Amazon Linux EC2
__| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2016.09-release-notes/
python
$ python -V Python 2.7.12
virtualenv
$ virtualenv --version 12.0.7
再現手順
virtualenvで環境作成し、pipでmarkupsafeをinstallし、 import markupsafe
行う
$ cd /tmp $ virtualenv --python=/usr/bin/python27 venv $ . venv/bin/activate (venv)$ pip install markupsafe You are using pip version 6.0.8, however version 9.0.1 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Collecting markupsafe Downloading MarkupSafe-0.23.tar.gz Installing collected packages: markupsafe Running setup.py install for markupsafe building 'markupsafe._speedups' extension gcc -pthread -fno-strict-aliasing -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/usr/include/python2.7 -c markupsafe/_speedups.c -o build/temp.linux-x86_64-2.7/markupsafe/_speedups.o gcc -pthread -shared build/temp.linux-x86_64-2.7/markupsafe/_speedups.o -L/usr/lib64 -lpython2.7 -o build/lib.linux-x86_64-2.7/markupsafe/_speedups.so Successfully installed markupsafe $ python Python 2.7.12 (default, Sep 1 2016, 22:14:00) [GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import markupsafe Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named markupsafe
事象の確認と原因
venv/lib64/python2.7/dist-packages
の中にmarkupsafeは存在している。
(venv)$ ls venv/lib64/python2.7/dist-packages/ MarkupSafe-0.23-py2.7.egg-info markupsafe
pip freeze
には出てこない
(venv)$ pip freeze You are using pip version 6.0.8, however version 9.0.1 is available. You should consider upgrading via the 'pip install --upgrade pip' command.
sys.path
の中身を確認して見ると、 /tmp/venv/lib64/python2.7/dist-packages
が含まれていない
(venv)$ python -c 'import sys;import pprint; pprint.pprint(sys.path)' ['', '/tmp/venv/local/lib64/python2.7/site-packages', '/tmp/venv/local/lib/python2.7/site-packages', '/tmp/venv/lib64/python2.7', '/tmp/venv/lib/python2.7', '/tmp/venv/lib64/python2.7/site-packages', '/tmp/venv/lib/python2.7/site-packages', '/tmp/venv/lib64/python2.7/lib-dynload', '/tmp/venv/local/lib/python2.7/dist-packages', '/tmp/venv/local/lib/python2.7/dist-packages', '/tmp/venv/lib/python2.7/dist-packages', '/usr/lib64/python2.7', '/usr/lib/python2.7']
sys.path
に /tmp/venv/lib64/python2.7/dist-packages
を追加して、importすると成功します。
(venv)$ python Python 2.7.12 (default, Sep 1 2016, 22:14:00) [GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import markupsafe Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named markupsafe >>> import sys >>> sys.path.append('/tmp/venv/lib64/python2.7/dist-packages') >>> import markupsafe >>>
どうやら、sys.pathに /tmp/venv/lib64/python2.7/dist-packages
が含まれておらずimportに失敗するのが原因のようです。
解決方法
OS側のpipとvirtualenvを更新し、virtualenvの環境を作り直します。
(venv)$ deactivate $ sudo -i # pip install --upgrade pip # pip install --upgrade virtualenv # exit
参考: django - python virtualenv ImportError with celery and billiard - Stack Overflow
動作確認
上記再現手順を行ってもエラーが出ないことが確認できました。
$ cd /tmp $ virtualenv --python=/usr/bin/python27 venv2 #先程作った環境とは別にvenv2を作成 $ . venv2/bin/activate (venv2)$ pip install markupsafe Collecting markupsafe Using cached MarkupSafe-0.23.tar.gz Building wheels for collected packages: markupsafe Running setup.py bdist_wheel for markupsafe ... done Stored in directory: /home/ec2-user/.cache/pip/wheels/a3/fa/dc/0198eed9ad95489b8a4f45d14dd5d2aee3f8984e46862c5748 Successfully built markupsafe Installing collected packages: markupsafe Successfully installed markupsafe-0.23 (venv2)$ python Python 2.7.12 (default, Sep 1 2016, 22:14:00) [GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import markupsafe >>>
pip freeze
にも表示されます。
(venv2)$ pip freeze MarkupSafe==0.23
sys.path
にも /tmp/venv2/lib/python2.7/dist-packages
が存在しませんが、 venv2/lib64
は venv2/lib
へシンボリックリンクが貼られているので参照出来るようになってます。
ここでもう一度 ls -l venv
の中を見てみると、アップグレード前の venv/lib64
はシンボリックリンクになっていません
(venv2)$ python -c 'import sys;import pprint; pprint.pprint(sys.path)' ['', '/tmp/venv2/lib/python27.zip', '/tmp/venv2/lib64/python2.7', '/tmp/venv2/lib64/python2.7/plat-linux2', '/tmp/venv2/lib64/python2.7/lib-tk', '/tmp/venv2/lib64/python2.7/lib-old', '/tmp/venv2/lib64/python2.7/lib-dynload', '/usr/lib64/python2.7', '/usr/lib/python2.7', '/tmp/venv2/local/lib/python2.7/site-packages', '/tmp/venv2/local/lib/python2.7/dist-packages', '/tmp/venv2/lib/python2.7/site-packages', '/tmp/venv2/local/lib/python2.7/dist-packages', '/tmp/venv2/lib/python2.7/dist-packages'] (venv2)$ ls -l venv2/ 合計 20 drwxrwxr-x 2 ec2-user ec2-user 4096 1月 18 06:03 bin drwxrwxr-x 2 ec2-user ec2-user 4096 1月 18 06:03 include drwxrwxr-x 3 ec2-user ec2-user 4096 1月 18 06:03 lib lrwxrwxrwx 1 ec2-user ec2-user 3 1月 18 06:03 lib64 -> lib drwxrwxr-x 2 ec2-user ec2-user 4096 1月 18 06:03 local -rw-rw-r-- 1 ec2-user ec2-user 60 1月 18 06:04 pip-selfcheck.json (venv2)$ ls -l venv/ 合計 24 drwxrwxr-x 2 ec2-user ec2-user 4096 1月 18 05:49 bin drwxrwxr-x 2 ec2-user ec2-user 4096 1月 18 05:49 include drwxrwxr-x 3 ec2-user ec2-user 4096 1月 18 05:49 lib drwxrwxr-x 3 ec2-user ec2-user 4096 1月 18 05:49 lib64 drwxrwxr-x 2 ec2-user ec2-user 4096 1月 18 05:49 local -rw-rw-r-- 1 ec2-user ec2-user 60 1月 18 05:50 pip-selfcheck.json
まとめ
markupsafe
のモジュールは、 大きいところですと Jinja2 を使用すると必要になるモジュールです。
Jinja2を使いたいのに、 markupsafe
のImportErrorでわからんという時は参考にしてもらえば幸いです。